<template>
  <button>
    <div
      class="wallet-button-content"
      @click="() => (isMobile() ? connectMobileWallet() : connectWallet())"
      v-if="!isConnecting"
    >
      <img
        class="wallet-button-content__logo"
        :src="firstConnector.icon ?? firstConnector.iconUrl"
      />
      <span class="wallet-button-content__label">{{
        firstConnector.name
      }}</span>
      <span class="wallet-button-dot" v-if="isLastWalletIdConnected"></span>
    </div>
    <div class="wallet-button-content" v-else>
      <Spinner :width="28" :height="28" />
      <div class="wallet-button-content__label">Connecting</div>
    </div>
  </button>

  <ScanConnectModal
    ref="scanConnectModalRef"
    :wallet="firstConnector"
    @close="closeScanModal"
  />
  <MobileConnectMiniModal
    ref="mobileConnectMiniModalRef"
    :wallet="firstConnector"
    @close="closeScanModal"
    @retry="connectMobileWallet"
  />
</template>
<script setup lang="ts">
import { useWalletConnectors } from '../../wallets/useWalletConnectors'
import { computed, inject, ref } from 'vue'
import Spinner from '../Icons/Spinner.vue'
import {
  addLatestWalletId,
  clearLatestWalletId,
  getLatestWalletId,
} from '../../wallets/latestWalletId'
import { Config, useAccount, useAccountEffect, useDisconnect } from '@wagmi/vue'
import ScanConnectModal from '../Modal/ScanConnectModal.vue'
import MobileConnectMiniModal from '../Modal/MobileConnectMiniModal.vue'
import { isMobile } from '../../utils/isMobile'
import { setWalletConnectDeepLink } from '../../wallets/walletConnectDeepLink'

// todo 这个组件有BUG，这里也要做一下服务端渲染兼容，暂时没时间就先不做

const scanConnectModalRef = ref()
const mobileConnectMiniModalRef = ref()
const props = withDefaults(
  defineProps<{
    wallet: string
  }>(),
  {},
)

const { isConnected, status } = useAccount()
const { disconnect } = useDisconnect()
const isConnecting = ref(false)

const [firstConnector] = useWalletConnectors()
  .filter(wallet => wallet.isWalletKitConnector)
  // rainbowkit / wagmi connectors can uppercase some letters on the `id` field.
  // Id for metamask is `metaMask`, so instead we will make sure it's has lowercase comparison
  .filter(_wallet => _wallet.id.toLowerCase() === props.wallet.toLowerCase())
  .sort((a, b) => a.groupIndex - b.groupIndex)

if (!firstConnector) {
  throw new Error('Connector not found')
}

const isLastWalletIdConnected = computed(() => {
  const lastWalletId = getLatestWalletId()

  if (!lastWalletId.value || !firstConnector?.name) {
    return false
  }

  // Sometimes localstorage might not be in sync
  // if component doesn't rerender, but for if user
  // is not connected don't show them the green badge
  if (!isConnected.value) return false

  return lastWalletId.value === firstConnector?.name
})

useAccountEffect({
  onDisconnect() {
    clearLatestWalletId()
  },
})

const closeScanModal = () => {
  if (status.value !== 'connected') {
    disconnect()
  }
}

const connectWallet = async () => {
  const open = scanConnectModalRef.value.open as () => void

  try {
    if (status.value === 'disconnected') {
      if (
        firstConnector.getQrCodeUri &&
        firstConnector.isWalletKitConnector &&
        firstConnector.ready &&
        !firstConnector.installed
      ) {
        open()
      } else if (firstConnector.ready) {
        isConnecting.value = true
        await firstConnector.connect()
        addLatestWalletId(firstConnector.name)
        isConnecting.value = false
      } else {
        open()
      }
    }
  } catch (_e: any) {
    isConnecting.value = false
  }
}

const connectMobileWallet = async () => {
  const openMini = mobileConnectMiniModalRef.value.open as () => void
  const closeMini = mobileConnectMiniModalRef.value.close as () => void

  if (status.value === 'disconnected') {
    const { connect, id, name, getMobileUri, showWalletConnectModal } =
      firstConnector
    openMini()
    addLatestWalletId(name)

    const onMobileUri = async () => {
      const mobileUri = await getMobileUri?.()

      if (!mobileUri) return

      if (mobileUri) {
        setWalletConnectDeepLink({ mobileUri, name })
      }

      if (mobileUri.startsWith('http')) {
        // Workaround for https://github.com/rainbow-me/rainbowkit/issues/524.
        // Using 'window.open' causes issues on iOS in non-Safari browsers and
        // WebViews where a blank tab is left behind after connecting.
        // This is especially bad in some WebView scenarios (e.g. following a
        // link from Twitter) where the user doesn't have any mechanism for
        // closing the blank tab.
        // For whatever reason, links with a target of "_blank" don't suffer
        // from this problem, and programmatically clicking a detached link
        // element with the same attributes also avoids the issue.
        const link = document.createElement('a')
        link.href = mobileUri
        link.target = '_blank'
        link.rel = 'noreferrer noopener'
        link.click()
      } else {
        window.location.href = mobileUri
      }
    }

    if (id !== 'walletConnect') onMobileUri()

    if (showWalletConnectModal) {
      showWalletConnectModal()
      closeMini()
      return
    }

    await connect()
    closeMini()
  }
}
</script>

<style lang="scss" scoped>
button {
  cursor: pointer;
  padding: 0;
}
.wallet-button-content {
  display: flex;
  padding: 6px;
  gap: 8px;
  align-items: center;
  .wallet-button-content__logo {
    width: 28px;
    height: 28px;
    flex-shrink: 0;
    border-radius: 4px;
  }
  .wallet-button-content__label {
    font-weight: bold;
    flex-shrink: 0;
  }
  .wallet-button-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #30e000;
    flex-shrink: 0;
  }
}
</style>
